#import "HHUserService.h"
#import "HHUserCenter.h"

#import "BDRSACryptor.h"
#import "BDRSACryptorKeyPair.h"

#import <HHToastKit/HHToastKit.h>
#import <BCFoundation/BCFoundation.h>
#import <HHNetworkKit/HHNetworkKit.h>

#import "QLKDeviceIdentifier.h"

@interface HHUserService ()

@property (nonatomic, strong, readwrite) HHUserConfig *config;

@end

@implementation HHUserService

///MARK: - HHUserServiceProtocol
- (void)userLogin:(NSString *)phoneNum password:(NSString *)pwd completion:(void (^_Nullable)(BOOL success, HHUserIdentites *_Nullable identites) )completion {
    dispatch_group_t group = dispatch_group_create();
    __block NSString *__loginKey, *__doctorId, *RSAPwd;

    dispatch_group_enter(group);
    [self fetchLoginKey:phoneNum completion:^(NSString *_Nonnull loginKey, NSString *_Nonnull doctorId) {
        __loginKey = loginKey;
        __doctorId = doctorId;
        dispatch_group_leave(group);
    }];

    dispatch_group_enter(group);
    @BCWeakify(self);
    [self fetchUserPublicKey:phoneNum completion:^(NSString *_Nonnull publicKey) {
        @BCStrongify(self);
        if (publicKey) {
            RSAPwd = [self RSAFormatPulicKey:publicKey password:pwd];
        }
        dispatch_group_leave(group);
    }];

    dispatch_group_notify(group, dispatch_get_main_queue(), ^{
        if (__loginKey && __doctorId && RSAPwd) {
            NSMutableDictionary *paramsDict = [[NSMutableDictionary alloc] init];
            paramsDict[@"doctorId"] = __doctorId;
            paramsDict[@"loginKey"] = __loginKey;
            paramsDict[@"password"] = RSAPwd;
            NSString *deviceIdentifier = [QLKDeviceIdentifier deviceIdentifier];
            if (!deviceIdentifier) {
                deviceIdentifier = [[[UIDevice currentDevice] identifierForVendor] UUIDString];
            }
            paramsDict[@"deviceSN"] = deviceIdentifier;

            [self userLoginWithParams:paramsDict completion:^(BOOL success, HHUserIdentites *_Nullable identites) {
                if (!identites) {
                    !completion ? : completion(NO, nil);
                    return;
                }
                @BCStrongify(self);
                if ([self.config synchroniseHuanxinLogin]) {
                    NSString *password = [[identites.ucUserId bc_md5] lowercaseString];
                    [self loginWithHuanxin:identites.ucUserId password:password completion:^(BOOL hxSuccess) {
                        if (hxSuccess) {
                            !completion ? : completion(hxSuccess, identites);
                        } else {
                            !completion ? : completion(NO, nil);
                        }
                    }];
                } else {
                    !completion ? : completion(success, identites);
                }
            }];
        } else {
            [HHToastManager showToast:@"登录失败，请重新登录"];
            !completion ? : completion(NO, nil);
        }
    });
}

- (void)getUserCenterInfoWithCompletion:(void (^)(HHUserModel *_Nullable userModel))completion {
    NSString *serviceUrl = HHFullURL(kHHHttpEnvDoctor, self.config.userCenterURL);
    NSMutableDictionary *mParams = [[NSMutableDictionary alloc] init];
    mParams[@"token"] = [HHUserCenter identites].token;
    mParams[@"doctorId"] = [HHUserCenter identites].doctorId;

    [HHHttpCom getURL:serviceUrl withParam:mParams withComplate:^(BCHttpRequestModel *_Nonnull request, BCHttpResponseModel *_Nonnull response) {
        HHUserModel *usrModel = nil;
        if (response.success) {
            NSDictionary *dataDict = HHUserResponeData(response.bc_data);
            usrModel = [HHUserModel yy_modelWithJSON:dataDict];
        }
        if (completion) {
            completion(usrModel);
        }
    } withTarget:self];
}

- (void)sendSms:(NSString *)phoneNum actionType:(NSInteger)type completion:(void (^_Nullable)(BOOL success) )completion {
    [self fetchServiceTime:^(NSString *_Nonnull timeValue) {
        if (!timeValue) {
            !completion ? : completion(NO);
            return;
        }
        NSString *signStr = [NSString stringWithFormat:@"actionType=%@&phoneNum=%@&t=%@%@", @(type), phoneNum, timeValue, self.config.userSmsSecretKey];

        NSMutableDictionary *mParams = [[NSMutableDictionary alloc] init];
        mParams[@"actionType"] = @(type);
        mParams[@"phoneNum"] = phoneNum;
        mParams[@"sign"] = signStr;
        mParams[@"t"] = timeValue;

        NSString *serviceUrl = HHFullURL(kHHHttpEnvDoctor, self.config.sendSmsURL);
        [HHHttpCom requestUrl:serviceUrl withParam:mParams withComplate:^(BCHttpRequestModel *_Nonnull request, BCHttpResponseModel *_Nonnull response) {
            if (completion) {
                completion(response.success);
            }
        } withTarget:self];
    }];
}

- (void)userLogin:(NSString *)phoneNum verifyCode:(NSString *)code completion:(void (^_Nullable)(BOOL success, HHUserIdentites *_Nullable identites) )completion {
    NSString *serviceUrl = HHFullURL(kHHHttpEnvDoctor, self.config.validLoginURL);
    NSMutableDictionary *mParams = [[NSMutableDictionary alloc] init];
    mParams[kZHNetwork_ShowErrorStyle] = @"alert";
    mParams[@"phoneNum"] = phoneNum;
    mParams[@"verifyCode"] = code;
    NSString *deviceIdentifier = [QLKDeviceIdentifier deviceIdentifier];
    if (!deviceIdentifier) {
        deviceIdentifier = [[[UIDevice currentDevice] identifierForVendor] UUIDString];
    }
    mParams[@"deviceSN"] = deviceIdentifier;

    @BCWeakify(self);
    [HHHttpCom requestUrl:serviceUrl withParam:mParams withComplate:^(BCHttpRequestModel *_Nonnull request, BCHttpResponseModel *_Nonnull response) {
        @BCStrongify(self);

        HHUserIdentites *identites = nil;
        if (response.success) {
            NSDictionary *dataDict = HHUserResponeData(response.bc_data);
            identites = [HHUserIdentites yy_modelWithJSON:dataDict];
        }
        if ([self.config synchroniseHuanxinLogin]) {
            NSString *password = [[identites.ucUserId bc_md5] lowercaseString];
            [self loginWithHuanxin:identites.ucUserId password:password completion:^(BOOL hxSuccess) {
                if (hxSuccess) {
                    !completion ? : completion(hxSuccess, identites);
                } else {
                    !completion ? : completion(NO, nil);
                }
            }];
        } else {
            !completion ? : completion(response.success, identites);
        }
    } withTarget:self];
}

///MARK: - login
- (void)fetchLoginKey:(NSString *)phoneNum completion:(void (^_Nullable)(NSString *loginKey, NSString *doctorId) )completion {
    NSString *serviceUrl = HHFullURL(kHHHttpEnvDoctor, self.config.userGenLoginKeyURL);
    NSMutableDictionary *mParams = [[NSMutableDictionary alloc] init];
    mParams[@"phoneNum"] = phoneNum;

    [HHHttpCom requestUrl:serviceUrl withParam:mParams withComplate:^(BCHttpRequestModel *_Nonnull request, BCHttpResponseModel *_Nonnull response) {
        NSString *loginKey, *doctorId;
        if (response.success) {
            NSDictionary *dataDict = HHUserResponeData(response.bc_data);
            loginKey = dataDict[@"loginKey"];
            doctorId = dataDict[@"doctorId"];
        }
        if (completion) {
            completion(loginKey, doctorId);
        }
    } withTarget:self];
}

- (void)fetchUserPublicKey:(NSString *)phoneNum completion:(void (^_Nullable)(NSString *publicKey) )completion {
    NSString *serviceUrl = HHFullURL(kHHHttpEnvDoctor, self.config.userGetPublicKeyURL);
    NSMutableDictionary *mParams = [[NSMutableDictionary alloc] init];
    mParams[@"phoneNum"] = phoneNum;

    [HHHttpCom requestUrl:serviceUrl withParam:mParams withComplate:^(BCHttpRequestModel *_Nonnull request, BCHttpResponseModel *_Nonnull response) {
        NSString *publicKey;
        if (response.success) {
            NSDictionary *dataDict = HHUserResponeData(response.bc_data);
            publicKey = dataDict[@"publicKey"];
        }
        if (completion) {
            completion(publicKey);
        }
    } withTarget:self];
}

- (void)userLoginWithParams:(NSDictionary *)params completion:(void (^_Nullable)(BOOL success, HHUserIdentites *_Nullable identites) )completion {
    NSString *serviceUrl = HHFullURL(kHHHttpEnvDoctor, self.config.userLoginURL);
    NSMutableDictionary *mParams = [[NSMutableDictionary alloc] initWithDictionary:params];
    mParams[kZHNetwork_ShowErrorStyle] = @"alert";

    [HHHttpCom requestUrl:serviceUrl withParam:mParams withComplate:^(BCHttpRequestModel *_Nonnull request, BCHttpResponseModel *_Nonnull response) {
        HHUserIdentites *identites = nil;
        if (response.success) {
            NSDictionary *dataDict = HHUserResponeData(response.bc_data);
            identites = [HHUserIdentites yy_modelWithJSON:dataDict];
        }
        if (completion) {
            completion(response.success, identites);
        }
    } withTarget:self];
}

- (void)loginWithHuanxin:(NSString *)username password:(NSString *)password completion:(void (^)(BOOL success))completion {

}

- (void)fetchServiceTime:(void (^_Nullable)(NSString *timeValue) )completion {
    NSString *serviceUrl = HHFullURL(kHHHttpEnvDoctor, self.config.userLoginURL);
    [HHHttpCom requestUrl:serviceUrl withParam:nil withComplate:^(BCHttpRequestModel *_Nonnull request, BCHttpResponseModel *_Nonnull response) {
        NSString *timeVal = nil;
        if (response.success) {
            id value = HHUserResponeData(response.bc_data);
            if ([value isKindOfClass:[NSString class]]) {
                timeVal = [NSString stringWithFormat:@"%@", value];
            }
        }
        if (completion) {
            completion(timeVal);
        }
    } withTarget:self];
}

///MARK: - config
- (void)changeUserConfig:(NSObject<HHUserConfigProtocol> *)config {
    _config.configDelegate = config;
}

///MARK: - getter
- (HHUserConfig *)config {
    if (!_config) {
        _config = [[HHUserConfig alloc] init];
    }
    return _config;
}

///MARK: - help
- (NSString *)RSAFormatPulicKey:(NSString *)publicKey password:(NSString *)password {
    NSString *X509PublicHeader = @"-----BEGIN PUBLIC KEY-----";
    NSString *X509PublicFooter = @"-----END PUBLIC KEY-----";
    NSString *tempStr = [[[publicKey stringByReplacingOccurrencesOfString:@"\n"
                                                               withString:@""] stringByReplacingOccurrencesOfString:@" " withString:@""]stringByReplacingOccurrencesOfString:@"\r" withString:@""];
    tempStr = [[NSString alloc] initWithFormat:@"%@\n%@\n%@", X509PublicHeader, tempStr, X509PublicFooter];

    BDError *error = [[BDError alloc] init];
    BDRSACryptor *RSACryptor = [[BDRSACryptor alloc] init];
    NSString *cipherText =
        [RSACryptor encrypt:password
                        key:tempStr
                      error:error];
    return cipherText;
}

///MARK: - until
id HHUserResponeData(NSDictionary *responseData)
{
    NSArray *dataArr = responseData[@"data"];
    if ([dataArr isKindOfClass:[NSArray class]]) {
        return [dataArr firstObject];
    } else {
        return dataArr;
    }
}

@end
